package cn.zswltech.gruul.biz.service.impl;

import cn.zswltech.gruul.biz.service.SystemConfigService;
import cn.zswltech.gruul.biz.support.impl.IServiceImpl;
import cn.zswltech.gruul.common.result.MSG;
import cn.zswltech.gruul.common.result.Response;
import cn.zswltech.gruul.web.api.util.AccountUtil;
import cn.zswltech.gruul.common.dal.dao.SystemConfigDOMapper;
import cn.zswltech.gruul.common.entity.SystemConfigDO;
import cn.zswltech.gruul.common.dal.query.SystemConfigQuery;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


@Service("systemConfigServiceAPI")
public class SystemConfigServiceImpl extends IServiceImpl<SystemConfigDO> implements SystemConfigService {
    private final static Logger logger = LoggerFactory.getLogger(SystemConfigServiceImpl.class);

    @Autowired
    private SystemConfigDOMapper systemConfigDOMapper;

//    @Autowired
//    private NoticeMsgService noticeMsgService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response deleteConfig(Long id) {
        Response response = new Response();
        try {
            if (id == null) {
                response.setMessage(MSG.req_error_param_null, "id");
                return response;
            }
            SystemConfigDO query = new SystemConfigDO();
            query.setId(id);
            systemConfigDOMapper.delete(query);
            return response.success(null);
        } catch (Exception e) {
            logger.error("API create system config list error", e);
        }
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response updateConfig(SystemConfigDO systemConfigDO) {
        Response response = new Response();
        if (systemConfigDO.getId() == null) {
            response.setMessage(MSG.req_error_param_null, "id");
            return response;
        }
        try {
            SystemConfigDO systemConfigIndb = systemConfigDOMapper.selectByPrimaryKey(systemConfigDO.getId());
            if (systemConfigIndb == null) {
                response.setMessage(MSG.req_error_nodata);
                return response;
            }
            // 校验格式
            if (StringUtils.isNotBlank(systemConfigDO.getConfigValue())) {
                if ("Json".equalsIgnoreCase(systemConfigIndb.getType())) {
                    try {
                        String value = systemConfigIndb.getConfigValue();
                        if (value.trim().startsWith("[")) {
                            JSONArray.parseArray(value);
                        } else if (value.trim().startsWith("{")) {
                            JSONObject.parseObject(value);
                        }
                    } catch (Exception e) {
                        logger.error("JSONArray parse array error", e);
                        response.setMessage(MSG.req_error_param_format_error, "configValue");
                        return response;
                    }
                } else if ("Boolean".equalsIgnoreCase(systemConfigIndb.getType())) {
                    String value = systemConfigDO.getConfigValue();
                    if (!"true".equalsIgnoreCase(value) && !"false".equalsIgnoreCase(value)) {
                        response.setMessage(MSG.req_error_param_invalid, "configValue");
                        return response;
                    }
                }
                systemConfigIndb.setConfigValue(systemConfigDO.getConfigValue());
            }
            if (StringUtils.isNotBlank(systemConfigDO.getDescription())) {
                systemConfigIndb.setDescription(systemConfigDO.getDescription());
            }

            String account = AccountUtil.getLoginInfo().getAccount();
            Date now = new Date();
            systemConfigDO.setUpdatedBy(account);
            systemConfigDO.setGmtModified(now);
            systemConfigDOMapper.updateByPrimaryKeySelective(systemConfigIndb);
            // TODO 重要配置变更可消息通知
//            if (SystemConfigsConstants.KEY_LIMIT_FIELD.equals(systemConfigDO.getConfigKey()) || SystemConfigsConstants.KEY_DEGRADE_FIRST.equals(systemConfigDO.getConfigKey())) {
//                noticeMsgService.save("REFRESH_SYSTEM_CONFIG_CACHE", null);
//            }

            return Response.success(null);
        } catch (Exception e) {
            logger.error("API update system config error", e);
        }
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response<String> createConfig(SystemConfigDO systemConfigDO) {
        Response<String> response = new Response<String>();
        try {
            if (StringUtils.isBlank(systemConfigDO.getConfigKey())) {
                response.setMessage(MSG.req_error_param_null, "key");
                return response;
            }
            if (StringUtils.isBlank(systemConfigDO.getConfigValue())) {
                response.setMessage(MSG.req_error_param_null, "value");
                return response;
            }
            if (StringUtils.isBlank(systemConfigDO.getType())) {
                response.setMessage(MSG.req_error_param_null, "type");
                return response;
            }
            String type = systemConfigDO.getType();
            if (!"String".equalsIgnoreCase(type) && !"Boolean".equalsIgnoreCase(type) && !"Json".equalsIgnoreCase(type)) {
                response.setMessage(MSG.req_error_param_invalid, "type");
                return response;
            }
            String account = AccountUtil.getLoginInfo().getAccount();
            Date now = new Date();
            systemConfigDO.setCreatedBy(account);
            systemConfigDO.setUpdatedBy(account);
            systemConfigDO.setGmtCreate(now);
            systemConfigDO.setGmtModified(now);
            systemConfigDOMapper.insert(systemConfigDO);
            return response.success(systemConfigDO.getId().toString());
        } catch (Exception e) {
            logger.error("API create system config error", e);
            if (e.getMessage().contains("Duplicate entry 'key' for key 'key_'")) {
                response.setMessage(MSG.req_error_duplicate_key, "key");
                return response;
            } else if (e.getMessage().contains("Data too long for column 'config_key'")) {
                response.setMessage(MSG.req_error_param_too_long, "key");
                return response;
            } else if (e.getMessage().contains("Data too long for column 'config_value'")) {
                response.setMessage(MSG.req_error_param_too_long, "value");
                return response;
            } else if (e.getMessage().contains("Data too long for column 'description'")) {
                response.setMessage(MSG.req_error_param_too_long, "description");
                return response;
            }
        }
        return response;
    }

    @Override
    public Response<Map<String, Object>> getConfigList(SystemConfigQuery query) {
        Response<Map<String, Object>> response = new Response<Map<String, Object>>();
        Map<String, Object> dataMap = new HashMap<String, Object>();
        try {
            int count = systemConfigDOMapper.queryPageCount(query);
            if (count == 0) {
                dataMap.put("configList", new ArrayList<>(0));
                handleQueryParams(dataMap, query);
                return Response.success(dataMap);
            }
            query.setTotalResultCount(count);
            dataMap.put("configList", systemConfigDOMapper.queryPage(query));
            handleQueryParams(dataMap, query);
            return Response.success(dataMap);
        } catch (Exception e) {
            logger.error("API get system config list error", e);
        }
        return response;
    }

    @Override
    public Response<SystemConfigDO> getConfig(String key) {
        Response<SystemConfigDO> response = new Response<SystemConfigDO>();
        try {
            if (StringUtils.isBlank(key)) {
                response.setMessage(MSG.req_error_param_null, "key");
                return response;
            }
            SystemConfigDO query = new SystemConfigDO();
            query.setConfigKey(key);
            return response.success(systemConfigDOMapper.selectOne(query));
        } catch (Exception e) {
            logger.error("API get system config error", e);
        }
        return response;
    }

    @Override
    public Response getConfigValue(String key) {
        Response<Object> response = new Response<>();
        try {
            if (StringUtils.isBlank(key)) {
                response.setMessage(MSG.req_error_param_null, "key");
                return response;
            }
            SystemConfigDO query = new SystemConfigDO();
            query.setConfigKey(key);
            SystemConfigDO systemConfigIndb = systemConfigDOMapper.selectOne(query);
            if (systemConfigIndb == null) {
                response.setMessage(MSG.req_error_nodata);
                return response;
            }
            Object val = null;
            String type = systemConfigIndb.getType();
            String value = systemConfigIndb.getConfigValue();
            if (StringUtils.isBlank(value)) {
                response.setMessage(MSG.biz_error);
                return response;
            }
            if ("Json".equalsIgnoreCase(type)) {
                if (value.trim().startsWith("[")) {
                    val = JSONArray.parseArray(value);
                } else if (value.trim().startsWith("{")) {
                    val = JSONObject.parseObject(value);
                }
            } else if ("Boolean".equalsIgnoreCase(type)) {
                val = Boolean.valueOf(value);

            } else if ("String".equalsIgnoreCase(type)) {
                val = value;
            }
            return Response.success(val);
        } catch (Exception e) {
            logger.error("API get system config error", e);
        }
        return response;
    }

    @Override
    public Response<List<SystemConfigDO>> queryListByConfigs(List<String> configKeyList) {

        Response<List<SystemConfigDO>> response = new Response();
        try {
            if (CollectionUtils.isEmpty(configKeyList)) {
                response.setMessage(MSG.req_error_param_null, "key");
                return response;
            }
            return Response.success(systemConfigDOMapper.queryListByConfigs(configKeyList));
        } catch (Exception e) {
            logger.error("API get system configs error", e);
        }
        return response;
    }

    @Override
    public String getStringConfigValue(String key) {
        Response<SystemConfigDO> config = getConfig(key);
        if (config != null && config.getSuccess() && config.getData()!= null) {
            return config.getData().getConfigValue();
        }
        return null;
    }
}
